package org.mili.ticketeer.report;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.mili.core.templating.TemplateStore;
import org.mili.ticketeer.dto.Contact;
import org.mili.ticketeer.service.ServiceException;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class NameListGenerator extends AbstractGenerator {

    public NameListGenerator(ReportEngine reportEngine, TemplateStore templateStore) {
        super(reportEngine, templateStore);
    }

    public void generate() throws IOException, ServiceException {
        StringBuilder s = new StringBuilder();
        Map<String, Map<String, Set<Contact>>> model = reportEngine.getSpeakersByStreet();
        String temp = templateStore.get("members_Speakers");
        for(Map.Entry<String, Map<String, Set<Contact>>> entry : model.entrySet()) {
            String street = entry.getKey();
            String oldNumber = "";
            List<String> numbers = new ArrayList<String>(entry.getValue().keySet());
            Collections.sort(numbers, new StreeNumberComparator());
            for(String number : numbers) {
                String printedStreet = StringEscapeUtils.escapeHtml(street);
                String printedStreetnumber = StringEscapeUtils.escapeHtml(number);
                if (!number.equals(oldNumber)) {
                    oldNumber = number;
                } else {
                    printedStreet = "";
                    printedStreetnumber = "";
                }
                boolean first = true;
                List<Contact> speakers = new ArrayList<Contact>(entry.getValue().get(number));
                Collections.sort(speakers, new NameComparator());
                for(Contact speaker : speakers) {
                    if (speaker.isActive()) {
                        s.append(temp
                                .replace("${street}", printedStreet)
                                .replace("${street_number}", printedStreetnumber)
                                .replace("${firstname}", speaker.getFirstName())
                                .replace("${lastname}", speaker.getLastName())
                                .replace("${phone}", speaker.getPhone())
                                .replace("${email}", printEmail(speaker.getEmail()))
                                .replace("${sex}", reportEngine.printSex(speaker.getSex()))
                        );
                    }
                    if (first) {
                        printedStreet = "";
                        printedStreetnumber = "";
                    }
                    first = false;
                }
            }
        }
        FileUtils.writeStringToFile(new File("./tmp/out/haussprecher.html"),
                templateStore.get("members_Main")
                        .replace("${Speakers}", s)
                        .replace("${date}", "TEST")
                        .replace("${title}", "Haussprecher der Siedlung Spandau")
        );
    }

    private String printEmail(String email) {
        if (StringUtils.isEmpty(email)) {
            return email;
        }
        return "E-Mail:&nbsp;" + email;
    }

}

class NameComparator implements Comparator<Contact> {
    @Override
    public int compare(Contact o1, Contact o2) {
        return (o1.getLastName() + o1.getFirstName()).compareTo(o2.getLastName()
                + o2.getFirstName());
    }
}

class StreeNumberComparator implements Comparator<String> {
    @Override
    public int compare(String s1, String s2) {
        int n1 = -1;
        int n2 = -1;
        try {
            n1 = Integer.parseInt(filter(s1));
        } catch (NumberFormatException e) {
        }
        try {
            n2 = Integer.parseInt(filter(s2));
        } catch (NumberFormatException e) {
        }
        if (n1 > 0 && n2 > 0) {
            return n1 - n2;
        } else if (n1 < 0) {
            return -1;
        } else if (n2 < 0) {
            return 1;
        }
        return 0;
    }

    private String filter(String s1) {
        return s1.replaceAll("[a-zA-Z]", "");
    }
}